package uk.co.mmscomputing.sound.provider;
import javax.sound.sampled.*;
import uk.co.mmscomputing.concurrent.*;
class SpeakerThread extends Thread{
boolean isrunning=false;
private javax.sound.sampled.SourceDataLine speaker=null;
private DataLine[] sources=null;
private ArrayBlockingQueue queue=new ArrayBlockingQueue(10);
public SpeakerThread(DataLine[] sources)throws LineUnavailableException{
this.sources=sources;
AudioFormat format=sources[0].getFormat();
int bufsize=sources[0].getBufferSize();
speaker=getSpeaker(format,bufsize); // Get an output line from the audio system.
for(int i=0;i<sources.length;i++){
sources[i].setSpeakerThread(this);
}
}
private javax.sound.sampled.SourceDataLine getSpeaker(AudioFormat format,int bufsize)
throws LineUnavailableException
{
javax.sound.sampled.DataLine.Info info;
javax.sound.sampled.Mixer.Info[] infos;
javax.sound.sampled.Mixer mixer;
javax.sound.sampled.SourceDataLine speaker;
infos = AudioSystem.getMixerInfo();
info = new javax.sound.sampled.DataLine.Info(javax.sound.sampled.SourceDataLine.class,format);
for(int i=0;i<infos.length;i++){
mixer=AudioSystem.getMixer(infos[i]);
if(!(mixer instanceof uk.co.mmscomputing.sound.provider.Mixer) ){
// System.err.println("SPEAKER : "+mixer.getMixerInfo().getName());
try{
speaker=(javax.sound.sampled.SourceDataLine)mixer.getLine(info);
speaker.open(format,bufsize);
return speaker;
}catch(IllegalArgumentException iae){
}catch(LineUnavailableException lue){
}
}
}
throw new LineUnavailableException(getClass().getName()+".run() : \n\tNo microphone available.");
}
void flush(DataLine source){
for(int i=0;i<sources.length;i++){
if(sources[i].isActive()){
if(sources[i]==source){ // if the first active line is the source
queue.offer(new byte[0]); // put empty buffer into queue to flush speaker
}
return;
}
}
}
void put(DataLine source,byte[] buf){
for(int i=0;i<sources.length;i++){
if(sources[i].isActive()){
if(sources[i]==source){ // if the first active line is the source
try{queue.put(buf); // put buffer into queue
}catch(InterruptedException ie){}
}
return;
}
}
}
public void run(){
byte[] buf;
try{
isrunning=true;
speaker.flush();
speaker.start();
while(isrunning){
buf=(byte[])queue.take(); // wait for sound data
if(buf.length==0){ // from flush
speaker.flush();
}else{
speaker.write(buf,0,buf.length);// write to speaker
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
speaker.stop();speaker.flush();speaker.close();
}
}
}